package game.telemetry
{
	import away3d.core.managers.*;
	
	import engine.core.*;
	import engine.network.*;
	
	import flash.system.*;
	import flash.utils.*;
	
	import game.graphics.away3d.*;
	import game.messages.telemetry.*;
	import game.network.*;
	
	public class RxPerformanceTelemetry
	{
		public static const MODE_DISABLED:uint = 0;
		public static const MODE_BOOT:uint = 1;
		public static const MODE_LOADING_MAP:uint = 2;
		public static const MODE_PLAYING_MAP:uint = 3;
		public static const TIMER_PAGING:String = "pageTimer";
		private static var m_mode:uint = 0;
		private static var m_modeStartTime:int;
		private static var m_mapLoadTime:int;
		private static const TELEMETRY_MESSAGE_PING_TIME_MS:int = 10000;
		private static var m_sendTelemetryMessageTime:int;
		private static var m_numSampleFrames:uint;
		private static var m_minFrameTime:Number;
		private static var m_maxFrameTime:Number;
		private static var m_memoryStats:Vector.<Number> = new Vector.<Number>(3);
		private static var m_backbufferSizeStats:Vector.<Number> = new Vector.<Number>(3);
		private static var m_timerStartTimes:Object;
		private static var m_timerAccumulatedTimes:Object;
		private static var m_timeInGraphicModes:Vector.<Number> = new Vector.<Number>((RxRenderer.GRAPHICS_QUALITY_ULTRA + 1));

		public function RxPerformanceTelemetry()
		{
		}
		
		public static function SetMode(mode:uint) : void
		{
			var key:String = null;
			var dis:int = 0;
			if (m_mode == mode)
			{
				return;
			}
			var timer:* = getTimer();
			for (key in m_timerStartTimes)
			{
				
				dis = timer - m_timerStartTimes[key];
				m_timerAccumulatedTimes[key] = dis + m_timerAccumulatedTimes[key];
			}
			switch(m_mode)
			{
				case MODE_BOOT:
				case MODE_PLAYING_MAP:
				{
					SendTelemetryMessage();
					break;
				}
				case MODE_LOADING_MAP:
				{
					m_mapLoadTime = timer - m_modeStartTime;
					break;
				}
				default:
				{
					break;
				}
			}
			Reset();
			m_modeStartTime = timer;
			m_sendTelemetryMessageTime = mode == MODE_PLAYING_MAP ? (m_modeStartTime + TELEMETRY_MESSAGE_PING_TIME_MS) : (int.MAX_VALUE);
			m_timerStartTimes = new Object();
			m_timerAccumulatedTimes = new Object();
			m_mode = mode;
		}
		
		private static function Reset() : void
		{
			m_numSampleFrames = 0;
			m_minFrameTime = Number.MAX_VALUE;
			m_maxFrameTime = 0;
			m_memoryStats[0] = m_backbufferSizeStats[0] = Number.MAX_VALUE;
			m_memoryStats[1] = m_backbufferSizeStats[1] = 0;
			m_memoryStats[2] = m_backbufferSizeStats[2] = 0;
			m_timerStartTimes = new Object();
			m_timerAccumulatedTimes = new Object();
			var _local1:int;
			while (_local1 < m_timeInGraphicModes.length)
			{
				m_timeInGraphicModes[_local1] = 0;
				_local1++;
			}
		}
		
		private static function SendTelemetryMessage() : void
		{
			var _loc_2:RxRenderer = null;
			var _loc_3:RxTelemetry_BootPerformance = null;
			var _loc_4:RxTelemetry_MapPlayPerformance = null;
			var _loc_5:Number = NaN;
			var _loc_6:Number = NaN;
			var _loc_7:int = 0;
			var _loc_1:RxNetMessageBase = null;
			switch(m_mode)
			{
				case MODE_BOOT:
				{
					_loc_2 = RxRenderer.GetInstance();
					_loc_3 = new RxTelemetry_BootPerformance();
					_loc_3.bootTime = (getTimer() - m_modeStartTime) * 0.001;
					_loc_3.maxMemory = m_memoryStats[2];
					_loc_3.pageTime = m_timerAccumulatedTimes.hasOwnProperty(TIMER_PAGING) ? (m_timerAccumulatedTimes[TIMER_PAGING] * 0.001) : (0);
					_loc_3.gpuFillRateScore = _loc_2.GetGPUPerfScore();
					_loc_3.gpuFillRateTestTime = _loc_2.GetGPUPerfTime();
					_loc_3.cpuScore = _loc_2.GetCPUPerfScore();
					_loc_3.cpuTestTime = _loc_2.GetCPUPerfTime();
					_loc_1 = _loc_3 as RxNetMessageBase;
					break;
				}
				case MODE_PLAYING_MAP:
				{
					_loc_4 = new RxTelemetry_MapPlayPerformance();
					_loc_4.totalPlayTime = (getTimer() - m_modeStartTime) * 0.001;
					_loc_4.backbufferSize = m_backbufferSizeStats;
					_loc_4.framesPerSec.length = 3;
					_loc_4.framesPerSec[0] = 1 / m_maxFrameTime;
					_loc_4.framesPerSec[1] = m_numSampleFrames / _loc_4.totalPlayTime;
					_loc_4.framesPerSec[2] = 1 / m_minFrameTime;
					_loc_4.loadTime = m_mapLoadTime * 0.001;
					_loc_4.memoryUsage = m_memoryStats;
					_loc_5 = 0;
					_loc_6 = Number.MIN_VALUE;
					_loc_4.primaryGraphicsQuality = 0;
					_loc_7 = 0;
					while (_loc_7 < m_timeInGraphicModes.length)
					{
						
						_loc_5 = _loc_5 + m_timeInGraphicModes[_loc_7];
						if (m_timeInGraphicModes[_loc_7] > _loc_6)
						{
							_loc_6 = m_timeInGraphicModes[_loc_7];
							_loc_4.primaryGraphicsQuality = _loc_7;
						}
						_loc_7++;
					}
					_loc_4.ratioOfTimeInPrimaryGraphicsQuality = _loc_5 > 0 ? (_loc_6 / _loc_5) : (0);
					_loc_1 = _loc_4 as RxNetMessageBase;
					break;
				}
				default:
				{
					break;
				}
			}
			if (_loc_1 != null)
			{
				RxTransactionServer.instance.SendMessage(_loc_1);
			}
		}
		
		public static function Update() : void
		{
			var _loc_4:RxRenderer = null;
			var _loc_5:Stage3DProxy = null;
			var _loc_6:int = 0;
			var _loc_7:int = 0;
			if (m_mode == MODE_DISABLED)
			{
				return;
			}
			var _loc_9:* = m_numSampleFrames + 1;
			m_numSampleFrames = _loc_9;
			var _loc_1:* = RxTick.frameTime;
			if (m_minFrameTime > _loc_1)
			{
				m_minFrameTime = _loc_1;
			}
			if (m_maxFrameTime < _loc_1)
			{
				m_maxFrameTime = _loc_1;
			}
			var _loc_2:* = System.totalMemoryNumber;
			if (m_memoryStats[0] > _loc_2)
			{
				m_memoryStats[0] = _loc_2;
			}
			if (m_memoryStats[2] < _loc_2)
			{
				m_memoryStats[2] = _loc_2;
			}
			m_memoryStats[1] = m_memoryStats[1] + (_loc_2 - m_memoryStats[1]) / m_numSampleFrames;
			if (m_mode == MODE_PLAYING_MAP)
			{
				_loc_4 = RxRenderer.GetInstance();
				_loc_5 = _loc_4 != null ? (_loc_4.GetStage3DProxy()) : (null);
				_loc_6 = _loc_5 != null ? (_loc_5.backBufferHeight * _loc_5.backBufferWidth) : (0);
				if (m_backbufferSizeStats[0] > _loc_6)
				{
					m_backbufferSizeStats[0] = _loc_6;
				}
				if (m_backbufferSizeStats[2] < _loc_6)
				{
					m_backbufferSizeStats[2] = _loc_6;
				}
				m_backbufferSizeStats[1] = m_backbufferSizeStats[1] + (_loc_6 - m_backbufferSizeStats[1]) / m_numSampleFrames;
				_loc_7 = RxRenderer.GetInstance().GetGraphicsQuality();
				while (_loc_7 >= m_timeInGraphicModes.length)
				{
					
					m_timeInGraphicModes.push(0);
				}
				if (_loc_7 >= 0 && _loc_7 < m_timeInGraphicModes.length)
				{
					m_timeInGraphicModes[_loc_7] = m_timeInGraphicModes[_loc_7] + _loc_1;
				}
				else
				{
					RxLog.Error("Graphic quality level " + _loc_7 + " is out of bounds!");
				}
			}
			var _loc_3:* = getTimer();
			if (_loc_3 >= m_sendTelemetryMessageTime)
			{
				SendTelemetryMessage();
				m_sendTelemetryMessageTime = _loc_3 + TELEMETRY_MESSAGE_PING_TIME_MS;
			}
		}
	}
}